package hoyo.zqy.user.service.impl;

import hoyo.zqy.basic.exception.BusinessException;
import hoyo.zqy.basic.service.impl.BaseServiceImpl;
import hoyo.zqy.basic.util.Md5Utils;
import hoyo.zqy.basic.util.StrUtils;
import hoyo.zqy.user.domain.Logininfo;
import hoyo.zqy.user.domain.User;
import hoyo.zqy.user.mapper.LogininfoMapper;
import hoyo.zqy.user.mapper.UserMapper;
import hoyo.zqy.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Map;

/**
 * 业务实现类：
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LogininfoMapper logininfoMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JavaMailSender javaMailSender;

    /**
     * 手机注册
     * @param map
     */
    @Override
    public void phoneRegister(Map<String, String> map) {
        //导入参数
        String phone = map.get("phone");
        String phoneCode = map.get("phoneCode");
        String password = map.get("password");
        String passwordrepeat = map.get("passwordRepeat");
        //空值校验
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(phoneCode)||
                StringUtils.isEmpty(password) || StringUtils.isEmpty(passwordrepeat)){
            throw new BusinessException("请输入内容，小子");
        }
        //验证密码是否一致
        if(!password.equals(passwordrepeat)){
            throw new BusinessException("两次密码不相同");
        }
        //判断是否注册过
        User byPhone = userMapper.loadByPhone(phone);
        if (byPhone != null){
            throw new BusinessException("已经注册过了，小子");
        }
        //验证码校验是否过期
        //redis中调取数据
        Object obj = redisTemplate.opsForValue().get("register:" + phone);
        if (obj == null){
            throw new BusinessException("验证码已过期，请重新获取");
        }
        //验证码是否正确
        if (!phoneCode.equals(obj.toString().split(":")[0])){
            throw new BusinessException("验证码错误");
        }
        //存入数据库
        User user = map2User(phone,password);
        Logininfo logininfo = user2Logininfo(user);
        //添加loginifo优先
        logininfoMapper.save(logininfo);
        //在添加user
        user.setLogininfoId(logininfo.getId());
        userMapper.save(user);
    }
    private Logininfo user2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        //底层按照属性同名的原则进行属性copy
        BeanUtils.copyProperties(user,logininfo);
        logininfo.setType(1);//1表示用户
        logininfo.setDisable(true);//表示启用
        return logininfo;
    }

    private User map2User(String phone, String password) {
        User user = new User();
        user.setUsername(phone);
        user.setPhone(phone);
        //对密码进行加密
        String salt = StrUtils.getComplexRandomString(32);
        String md5 = Md5Utils.encrypByMd5(password + salt);
        user.setSalt(salt);
        user.setPassword(md5);
        user.setState(1);
        return user;
    }

    /**
     * 邮箱注册
     * @param map
     */
    @Override
    public void emailRegister(Map<String, String> map) throws MessagingException {
        //导入参数
        String email = map.get("email");
        String password = map.get("password");
        String passwordRepeat = map.get("passwordRepeat");
        //非空值校验
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(password)
                || StringUtils.isEmpty(passwordRepeat)){
            throw new BusinessException("值不能为空");
        }
        //检测密码是否一致
        if (!password.equals(passwordRepeat)){
            throw new BusinessException("两次输入密码不一致");
        }
        //检查是否注册过
        User userEmail = userMapper.loadByEmail(email);
        //赋值
        User user = map2User2(email,password);
        //同步给logininif
        Logininfo logininfo = user2Logininfo(user);
        //添加loginifo优先
        logininfoMapper.save(logininfo);
        //在添加user
        user.setLogininfoId(logininfo.getId());
        userMapper.save(user);
        //创建复杂邮件对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        //发送复杂邮件的工具类
        //true - 能够添加附件
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true,"utf-8");
        helper.setFrom("296072843@qq.com");
        helper.setSubject("用户激活邮件");
        //true - 能够再内容中编写html标签 - 会解析

        helper.setText("<h1>点击下发连接进行激活账户</h1><a href='http://127.0.0.1:8080/user/active/"+user.getId()+"'>点击该链接激活</a>",true);
        //添加附件
        helper.addAttachment("希儿.gif",new File("C:\\Users\\hoyo\\Desktop\\图包\\希儿.gif"));
        //收件人
        helper.setTo(email);
        javaMailSender.send(mimeMessage);
    }

    /**
     * 用户激活
     * @param id
     */
    @Override
    public void active(Long id) {
        User user = userMapper.loadById(id);
        user.setState(1);
        userMapper.update(user);
    }

    private User map2User2(String email, String password)  {
        User user = new User();
        user.setUsername(email);
        user.setEmail(email);
        //加密加颜值
        String salt = StrUtils.getComplexRandomString(32);
        String md5 = Md5Utils.encrypByMd5(password + salt);
        user.setPassword(md5);
        user.setSalt(salt);
        user.setState(0);
        return user;
    }

    /**
     * 保存
     * @param user
     */
    @Override
    public void save(User user) {
        //处理颜值密码
        String salt = StrUtils.getComplexRandomString(32);
        String md5 = Md5Utils.encrypByMd5(user.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(md5);
        //同步到logininfo
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
        logininfo.setType(1);
        logininfo.setDisable(true);
        //存入数据库，生成logininfo的ID
        logininfoMapper.save(logininfo);
        //添加LogininfoID
        user.setLogininfoId(logininfo.getId());
        super.save(user);
    }

    /**
     * 删除
     * @param id
     */
    @Override
    @Transactional
    public void delete(Long id) {
        //查询对应数据
        User user = userMapper.loadById(id);
        //根据数据内LogininfoID进行删除
        logininfoMapper.delete(user.getLogininfoId());
        super.delete(id);
    }

    /**
     * 修改
     * @param user
     */
    @Override
    public void update(User user) {
        //处理颜值密码
        String salt = StrUtils.getComplexRandomString(32);
        String md5 = Md5Utils.encrypByMd5(user.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(md5);

        //查询原来的user对象
        User olduser = userMapper.loadById(user.getId());
        user.setLogininfoId(olduser.getLogininfoId());

        super.update(user);
        //更新logininfo对象
        Logininfo oldlogininfo = logininfoMapper.loadById(olduser.getLogininfoId());
        //属性同名原则，logininfo的id也会被修改
        BeanUtils.copyProperties(user, oldlogininfo);
        //查询以前的user的logininfoID进行修正
        oldlogininfo.setId(olduser.getLogininfoId());
        logininfoMapper.update(oldlogininfo);
    }
}
